#include <linux/init.h>
#include <linux/module.h>

MODULE_LICENSE("Dual BSD/GPL");

struct s_a {
	int a;
	char c;
	__u64 array[10];
};

struct s_b {
	struct s_a a[1];
	__u64 array[20];
	struct s_a *b;
};

void gfp_test(void)
{
	struct s_b *b = NULL, *c = NULL, b_tmp[1];

	memset(b_tmp, 0, sizeof(struct s_b));

	b = (struct s_b *)kmalloc(sizeof(struct s_b) * 2, GFP_KERNEL | __GFP_ZERO);
	if (b == NULL)
		return;
	c = b + 1;
	
	printk(KERN_ERR "before memest\n");
	printk(KERN_ERR "first\n");
	if(memcmp(b, b_tmp, sizeof(struct s_b)) != 0) 
		printk(KERN_ERR "err\n");
	printk(KERN_ERR "second\n");
	if(memcmp(c, b_tmp, sizeof(struct s_b)) != 0) 
		printk(KERN_ERR "err\n");

	printk(KERN_ERR "after memest\n");
	printk(KERN_ERR "first\n");
	memset(b, 0, sizeof(struct s_b) * 2);
	if(memcmp(b, b_tmp, sizeof(struct s_b)) != 0) 
		printk(KERN_ERR "err\n");
	printk(KERN_ERR "second\n");
	if(memcmp(c, b_tmp, sizeof(struct s_b)) != 0) 
		printk(KERN_ERR "err\n");

	kfree(b);
}

static __init int test_init(void)
{
	printk(KERN_ERR "test init \n");
	gfp_test();
	return 0;
}

static __exit void test_exit(void)
{
	printk(KERN_ERR "test exit \n");
}

module_init(test_init);
module_exit(test_exit);

